package com.diaohaiwen.framework.mq.rocket.config;

import cn.hutool.core.util.ClassUtil;
import com.diaohaiwen.framework.mq.rocket.attrbute.RocketLister;
import com.diaohaiwen.framework.mq.rocket.properties.ClientProperties;
import org.apache.rocketmq.client.ClientConfig;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Stream;

import static com.diaohaiwen.common.constant.ConfigurationConstant.PACKAGE_ROOT;

/**
 * @author 刁海文
 * @since 2024/1/16 22:11
 */
public class BaseRocketConfig {

    final static Map<String, Map<String, Method>> METHOD_MAP = initial();

    public static void initial(ClientConfig config, ClientProperties properties) {
        config.setClientIP(properties.getClientIp());
        config.setInstanceName(properties.getInstanceName());
        config.setNamesrvAddr(properties.getServerAddr());
        config.setClientCallbackExecutorThreads(properties.getClientCallbackExecutorThreads());
        config.setPollNameServerInterval(properties.getPollNameServerInterval());
        config.setHeartbeatBrokerInterval(properties.getHeartbeatBrokerInterval());
        config.setPersistConsumerOffsetInterval(properties.getPersistConsumerOffsetInterval());
        config.setPullTimeDelayMillsWhenException(properties.getPullTimeDelayMillsWhenException());
        config.setUnitName(properties.getUnitName());
        config.setUnitMode(properties.isUnitMode());
        config.setVipChannelEnabled(properties.isVipChannelEnabled());
        config.setUseTLS(properties.isUseTLS());
        config.setNamespace(properties.getNamespace());
        config.setAccessChannel(properties.getChannel());
        config.setMqClientApiTimeout(properties.getMqClientApiTimeout());
    }


    private static Map<String, Map<String, Method>> initial() {

        Map<String, Map<String, Method>> map = new HashMap<>();
        ClassUtil.scanPackage(PACKAGE_ROOT).stream()
                .filter(clazz -> clazz.isAnnotationPresent(Component.class))
                .flatMap((Function<Class<?>, Stream<Method>>) aClass -> Arrays.stream(aClass.getMethods()))
                .filter(method -> method.isAnnotationPresent(RocketLister.class))
                .forEach(method -> {
                    RocketLister lister = method.getAnnotation(RocketLister.class);

                    String[] topics = lister.topics();
                    String[] tags = lister.tags();

                    for (String topic : topics) {
                        if (!map.containsKey(topic)) {
                            map.put(topic, new HashMap<>());
                        }

                        Map<String, Method> methodMap = map.get(topic);

                        for (String tag : tags) {
                            if (methodMap.containsKey(tag)) {
                                throw new RuntimeException(String.format("Class [%s] Method [%s] Topic [%s] Tags [%s] 重复", method.getDeclaringClass().getCanonicalName(), method.getName(), topic, tag));
                            }

                            methodMap.put(tag, method);
                        }
                    }

                });

        return map;
    }
}
